"""Data models for Auto Review tool."""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, List, Optional


@dataclass
class PullRequest:
    """Pull Request data model."""

    number: int
    title: str
    html_url: str
    url: str
    state: str
    draft: bool
    created_at: datetime
    updated_at: datetime
    user: Dict[str, Any]
    labels: List[Dict[str, Any]]
    body: str = ""

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "PullRequest":
        """Create PullRequest from API response dictionary."""
        from dateutil import parser

        return cls(
            number=data["number"],
            title=data.get("title", ""),
            html_url=data.get("html_url", ""),
            url=data.get("url", ""),
            state=data.get("state", "open"),
            draft=data.get("draft", False),
            created_at=parser.parse(data.get("created_at", datetime.now().isoformat())),
            updated_at=parser.parse(data.get("updated_at", datetime.now().isoformat())),
            user=data.get("user", {}),
            labels=data.get("labels", []),
            body=data.get("body", ""),
        )


@dataclass
class Issue:
    """Issue data model."""

    number: str
    title: str
    state: str
    body: str
    html_url: str
    user: Optional[Dict[str, Any]] = None
    labels: List[Dict[str, Any]] = field(default_factory=list)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "Issue":
        """Create Issue from API response dictionary."""
        return cls(
            number=str(data.get("number", "")),
            title=data.get("title", ""),
            state=data.get("state", "open"),
            body=data.get("body", ""),
            html_url=data.get("html_url", ""),
            user=data.get("user"),
            labels=data.get("labels", []),
        )


@dataclass
class ReviewIssue:
    """Individual issue found during code review."""

    description: str
    location: str
    suggestion: str
    severity: str  # critical/high/medium/low
    before_code: str = ""  # Code before modification
    after_code: str = ""  # Code after modification


@dataclass
class ReviewResult:
    """Code review result."""

    repo_name: str
    pr_number: int
    pr_title: str
    pr_url: str
    summary: str
    severity: str  # critical/high/medium/low
    severity_score: float  # 0-1
    critical_issues: List[ReviewIssue] = field(default_factory=list)
    high_issues: List[ReviewIssue] = field(default_factory=list)
    medium_issues: List[ReviewIssue] = field(default_factory=list)
    low_issues: List[ReviewIssue] = field(default_factory=list)
    positives: List[str] = field(default_factory=list)
    suggestions: List[str] = field(default_factory=list)
    issue_comparison: str = ""
    generated_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> Dict[str, Any]:
        """Convert ReviewResult to dictionary for storage."""
        return {
            "repo_name": self.repo_name,
            "pr_number": self.pr_number,
            "pr_title": self.pr_title,
            "pr_url": self.pr_url,
            "summary": self.summary,
            "severity": self.severity,
            "severity_score": self.severity_score,
            "critical_issues": [
                {
                    "description": issue.description,
                    "location": issue.location,
                    "suggestion": issue.suggestion,
                    "severity": issue.severity,
                    "before_code": issue.before_code,
                    "after_code": issue.after_code,
                }
                for issue in self.critical_issues
            ],
            "high_issues": [
                {
                    "description": issue.description,
                    "location": issue.location,
                    "suggestion": issue.suggestion,
                    "severity": issue.severity,
                    "before_code": issue.before_code,
                    "after_code": issue.after_code,
                }
                for issue in self.high_issues
            ],
            "medium_issues": [
                {
                    "description": issue.description,
                    "location": issue.location,
                    "suggestion": issue.suggestion,
                    "severity": issue.severity,
                    "before_code": issue.before_code,
                    "after_code": issue.after_code,
                }
                for issue in self.medium_issues
            ],
            "low_issues": [
                {
                    "description": issue.description,
                    "location": issue.location,
                    "suggestion": issue.suggestion,
                    "severity": issue.severity,
                    "before_code": issue.before_code,
                    "after_code": issue.after_code,
                }
                for issue in self.low_issues
            ],
            "positives": self.positives,
            "suggestions": self.suggestions,
            "issue_comparison": self.issue_comparison,
            "generated_at": self.generated_at.isoformat(),
        }

